using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;



namespace CGShaderIntegration
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class HesseSebastianUniverse : Microsoft.Xna.Framework.DrawableGameComponent, IMatrices
    {
        public Matrix WorldMatrix { get; set; }
        public Matrix ViewMatrix { get; set; }
        public Matrix ProjectionMatrix { get; set; }

        private ContentManager Content;

        private HesseSebastianEarth earth;
        private float scaleEarth;
        private Vector3 positionEarth;
        private Matrix mat_wEarth;
        private float rotationAngleEarth;
        private Vector3 rotationAxis2;



        private HesseSebastianMoon moon;
        private float scaleMoon;
        private Vector3 positionMoon;
        private Matrix mat_wMoon;
        private Vector3 rotationAxis;
        private float rotationMoon;

        private HesseSebastianSun sun;
        private Matrix mat_wSun;
        private float scaleSun;
        private Vector3 positionSun;        

        public HesseSebastianUniverse(Game game)  : base(game)
        {
            game.Components.Add(this);
            this.Content = game.Content;
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {     
            base.Initialize();
        }

        // <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            moon = new HesseSebastianMoon(Content);
            scaleMoon = 0.2f;

            earth = new HesseSebastianEarth(Content);
            positionEarth = new Vector3(5, 0, 0);
            scaleEarth = 0.5f;

            rotationAngleEarth = 0.0f;
            rotationMoon = 0.0f;

            sun = new HesseSebastianSun(Content);
            scaleSun = 1.2f;
            mat_wSun = Matrix.CreateScale(scaleSun) * Matrix.CreateTranslation(new Vector3(0.0f, 0.0f, 0.0f));
            positionSun = new Vector3(mat_wSun.Translation.X, mat_wSun.Translation.Y, mat_wSun.Translation.Z);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {       
            
            rotationAngleEarth += 0.005f;
            rotationMoon += 0.03f;

            mat_wEarth = Matrix.CreateScale(scaleEarth) * Matrix.CreateRotationY(rotationAngleEarth) * Matrix.CreateTranslation(positionEarth) * Matrix.CreateRotationY(rotationAngleEarth);
                    
            rotationAxis = new Vector3(0, 0, 1);
            mat_wMoon = Matrix.CreateScale(scaleMoon) * Matrix.CreateTranslation(new Vector3(2, 0, 0))  *Matrix.CreateRotationY(rotationMoon) * Matrix.CreateTranslation(positionEarth) * Matrix.CreateRotationY(rotationAngleEarth);
            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {             

            //DrawModel(moon, mat_wMoon);
            earth.Draw(mat_wEarth, this.ViewMatrix, this.ProjectionMatrix);
            sun.Draw(mat_wSun, this.ViewMatrix, this.ProjectionMatrix);
            moon.Draw(mat_wMoon, this.ViewMatrix, this.ProjectionMatrix);
            base.Draw(gameTime);
        }


        public string GetName()
        {
            return ("Hesse Sebastian");
        }
    }
}
